home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Programming / Python-1.4 / Lib / mailbox.py < prev    next >
Text File  |  1998-06-24  |  4KB  |  187 lines

  1. #!/usr/local/bin/python
  2.  
  3. """Classes to handle Unix style, MMDF style, and MH style mailboxes."""
  4.  
  5.  
  6. import rfc822
  7. import os
  8. import regex
  9.  
  10. class _Mailbox:
  11.     def __init__(self, fp):
  12.         self.fp = fp
  13.         self.seekp = 0
  14.  
  15.     def seek(self, pos, whence=0):
  16.         if whence==1:        # Relative to current position
  17.             self.pos = self.pos + pos
  18.         if whence==2:        # Relative to file's end
  19.             self.pos = self.stop + pos
  20.         else:            # Default - absolute position
  21.             self.pos = self.start + pos
  22.  
  23.     def next(self):
  24.         while 1:
  25.             self.fp.seek(self.seekp)
  26.             try:
  27.                 self._search_start()
  28.             except EOFError:
  29.                 self.seekp = self.fp.tell()
  30.                 return None
  31.             start = self.fp.tell()
  32.             self._search_end()
  33.             self.seekp = stop = self.fp.tell()
  34.             if start <> stop:
  35.                 break
  36.         return rfc822.Message(_Subfile(self.fp, start, stop))
  37.  
  38. class _Subfile:
  39.     def __init__(self, fp, start, stop):
  40.         self.fp = fp
  41.         self.start = start
  42.         self.stop = stop
  43.         self.pos = self.start
  44.  
  45.     def read(self, length = None):
  46.         if self.pos >= self.stop:
  47.             return ''
  48.         if length is None:
  49.             length = self.stop - self.pos
  50.         self.fp.seek(self.pos)
  51.         self.pos = self.pos + length
  52.         return self.fp.read(length)
  53.  
  54.     def readline(self, length = None):
  55.         if self.pos >= self.stop:
  56.             return ''
  57.         if length is None:
  58.             length = self.stop - self.pos
  59.         self.fp.seek(self.pos)
  60.         data = self.fp.readline(length)
  61.         if len(data) < length:
  62.             length = len(data)
  63.         self.pos = self.pos + length
  64.         return data
  65.  
  66.     def tell(self):
  67.         return self.pos - self.start
  68.  
  69.     def seek(self, pos, whence=0):
  70.             if whence == 0:
  71.             self.pos = self.start + pos
  72.         elif whence == 1:
  73.             self.pos = self.pos + pos
  74.         elif whence == 2:
  75.             self.pos = self.stop + pos
  76.  
  77.     def close(self):
  78.         pass
  79.  
  80. class UnixMailbox(_Mailbox):
  81.     def _search_start(self):
  82.         while 1:
  83.             line = self.fp.readline()
  84.             if not line:
  85.                 raise EOFError
  86.             if line[:5] == 'From ':
  87.                 return
  88.  
  89.     def _search_end(self):
  90.         while 1:
  91.             pos = self.fp.tell()
  92.             line = self.fp.readline()
  93.             if not line:
  94.                 return
  95.             if line[:5] == 'From ':
  96.                 self.fp.seek(pos)
  97.                 return
  98.  
  99. class MmdfMailbox(_Mailbox):
  100.     def _search_start(self):
  101.         while 1:
  102.             line = self.fp.readline()
  103.             if not line:
  104.                 raise EOFError
  105.             if line[:5] == '\001\001\001\001\n':
  106.                 return
  107.  
  108.     def _search_end(self):
  109.         while 1:
  110.             pos = self.fp.tell()
  111.             line = self.fp.readline()
  112.             if not line:
  113.                 return
  114.             if line == '\001\001\001\001\n':
  115.                 self.fp.seek(pos)
  116.                 return
  117.  
  118. class MHMailbox:
  119.     def __init__(self, dirname):
  120.     pat = regex.compile('^[0-9][0-9]*$')
  121.     self.dirname = dirname
  122.     files = os.listdir(self.dirname)
  123.     self.boxes = []
  124.     for f in files:
  125.         if pat.match(f) == len(f):
  126.         self.boxes.append(f)
  127.  
  128.     def next(self):
  129.     if not self.boxes:
  130.         return None
  131.     fn = self.boxes[0]
  132.     del self.boxes[0]
  133.     fp = open(os.path.join(self.dirname, fn))
  134.     return rfc822.Message(fp)
  135.         
  136.     
  137. def _test():
  138.     import time
  139.     import sys
  140.     import string
  141.     import os
  142.  
  143.     args = sys.argv[1:]
  144.     if not args:
  145.         if os.environ.has_key('MAIL'):
  146.             mbox = os.environ['MAIL']
  147.         elif os.environ.has_key('MAIL'):
  148.             mbox = os.environ['USER']
  149.         else:
  150.             print "Who are you?"
  151.             return
  152.     else:
  153.         mbox = args[0]
  154.     if mbox[:1] == '+':
  155.         mbox = os.environ['HOME'] + '/Mail/' + mbox[1:]
  156.     elif not '/' in mbox:
  157.         mbox = '/usr/mail/' + mbox
  158.     if os.path.isdir(mbox):
  159.         mb = MHMailbox(mbox)
  160.     else:
  161.         fp = open(mbox, 'r')
  162.         mb = UnixMailbox(fp)
  163.     
  164.     msgs = []
  165.     while 1:
  166.         msg = mb.next()
  167.         if not msg:
  168.             break
  169.         msgs.append(msg)
  170.     if len(args) > 1:
  171.         num = string.atoi(args[1])
  172.         print 'Message %d body:'%num
  173.         msg = msgs[num-1]
  174.         msg.rewindbody()
  175.         sys.stdout.write(msg.fp.read())
  176.     else:
  177.         print 'Mailbox',mbox,'has',len(msgs),'messages:'
  178.         for msg in msgs:
  179.             f = msg.getheader('from')
  180.             s = msg.getheader('subject')
  181.             d = (msg.getheader('date'))
  182.             print '%20.20s   %18.18s   %-30.30s'%(f, d[5:], s)
  183.  
  184.  
  185. if __name__ == '__main__':
  186.     _test()
  187.